/* 
 * File:   Texture.cpp
 * Author: gilvolpe
 * 
 * Created on June 8, 2013, 9:52 AM
 */

#include "Texture.h"

#include "basicInformation.h"

GLint Texture::loadBitmap(char* filename) {
    
    static GLint numTexture = -1; // The counter of the current texture is increased
    
    FILE * file;
    char temp;
    long i;
    
    numTexture++;
    
    if ((file = fopen(filename, "rb")) == NULL) return (-1); // Open the file for reading

    fseek(file, 18, SEEK_CUR); /* start reading width & height */
    fread(&this->biWidth, sizeof (int), 1, file);

    fread(&this->biHeight, sizeof (int), 1, file);

    fread(&this->biPlanes, sizeof (short int), 1, file);
    if (this->biPlanes != 1) {
        printf("Planes from %s is not 1: %u\n", filename, this->biPlanes);
        return 0;
    }

    // read the bpp
    fread(&this->biBitCount, sizeof (unsigned short int), 1, file);
    if (this->biBitCount != 24) {
        printf("Bpp from %s is not 24: %d\n", filename, this->biBitCount);
        return 0;
    }

    fseek(file, 24, SEEK_CUR);

    // read the data.
    this->data = (char *) malloc(this->biWidth * this->biHeight * 3);
    if (this->data == NULL) {
        printf("Error allocating memory for color-corrected image data\n");
        return 0;
    }

    if ((i = fread(this->data, this->biWidth * this->biHeight * 3, 1, file)) != 1) {
        printf("Error reading image data from %s.\n", filename);
        return 0;
    }

    for (i = 0; i < (this->biWidth * this->biHeight * 3); i += 3) { // reverse all of the colors. (bgr -> rgb)
        temp = this->data[i];
        this->data[i] = this->data[i + 2];
        this->data[i + 2] = temp;
    }
    fclose(file); // Closes the file stream

    glBindTexture(GL_TEXTURE_2D, numTexture); // Bind the ID texture specified by the 2nd parameter

    // The next commands sets the texture parameters
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // If the u,v coordinates overflow the range 0,1 the image is repeated
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // The magnification function ("linear" produces better results)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); //The minifying function

    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); // We don't combine the color with the original surface color, use only the texture map.

    // Finally we define the 2d texture
    glTexImage2D(GL_TEXTURE_2D, 0, 3, this->biWidth, this->biHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, this->data);

    // And create 2d mipmaps for the minifying function
    gluBuild2DMipmaps(GL_TEXTURE_2D, 3, this->biWidth, this->biHeight, GL_RGB, GL_UNSIGNED_BYTE, this->data);

    free(this->data); // Free the memory we used to load the texture

    return (numTexture); // Returns the current texture OpenGL ID
}

